template < int i>
struct PiTerms
{
  static double value ()
  {
    double c_term = (1.0/ double ((i*2) -1));
    double c_signed_term = (i%2) ==0? - c_term:c_term ;
    return c_signed_term + PiTerms <i -1 >:: value ();
  }
};

template <>
struct PiTerms <1>
{
  static double value ()
  { return 1.0; }
};

template < int terms >
struct Pi
{
  static double value ()
  { return 4.0 * PiTerms <terms >:: value (); }
};
